#pragma once

#include <optional>
#include <string>

#include "http.h"
#include "util/strutil.h"


class HttpRequest
{
public:
    using Impl = beast::http::request<beast::http::string_body>;

    enum class Method
    {
        Unknown, Get, Post,
    };

public:
    HttpRequest(Impl &&request)
        : request_(std::move(request))
        , logInfo_(makeLogInfo(request_)) {}

    Method method() const;

    std::string_view uri() const {
        return request_.target();
    }

    std::string_view ext() const {
        return strutil::ext(request_.target());
    }

    std::string relative(const std::string_view &base) const;

    bool isGet() const {
        return method() == Method::Get;
    }

    bool isPost() const {
        return method() == Method::Post;
    }

    bool under(const std::string_view &base) const;

    const std::string &logInfo() const {
        return logInfo_;
    }

    std::string_view ifNonMatch() const;

    bool acceptGzip() const;

    std::string_view paramValueOf(const std::string_view &name) const;

private:
    static std::string makeLogInfo(const Impl &request);

private:
    const Impl request_;
    const std::string logInfo_;
    const std::optional<std::string> etag_;
};
